home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / math / ast53src.zip / CHARTS1.C < prev    next >
C/C++ Source or Header  |  1996-09-29  |  50KB  |  1,548 lines

  1. /*
  2. ** Astrolog (Version 5.30) File: charts1.c
  3. **
  4. ** IMPORTANT NOTICE: The graphics database and chart display routines
  5. ** used in this program are Copyright (C) 1991-1996 by Walter D. Pullen
  6. ** (Astara@msn.com, http://www.magitech.com/~cruiser1/astrolog.htm).
  7. ** Permission is granted to freely use and distribute these routines
  8. ** provided one doesn't sell, restrict, or profit from them in any way.
  9. ** Modification is allowed provided these notices remain with any
  10. ** altered or edited versions of the program.
  11. **
  12. ** The main planetary calculation routines used in this program have
  13. ** been Copyrighted and the core of this program is basically a
  14. ** conversion to C of the routines created by James Neely as listed in
  15. ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
  16. ** available from Matrix Software. The copyright gives us permission to
  17. ** use the routines for personal use but not to sell them or profit from
  18. ** them in any way.
  19. **
  20. ** The PostScript code within the core graphics routines are programmed
  21. ** and Copyright (C) 1992-1993 by Brian D. Willoughby
  22. ** (brianw@sounds.wa.com). Conditions are identical to those above.
  23. **
  24. ** The extended accurate ephemeris databases and formulas are from the
  25. ** calculation routines in the program "Placalc" and are programmed and
  26. ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
  27. ** (alois@azur.ch). The use of that source code is subject to
  28. ** regulations made by Astrodienst Zurich, and the code is not in the
  29. ** public domain. This copyright notice must not be changed or removed
  30. ** by any user of this program.
  31. **
  32. ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
  33. ** X Window graphics initially programmed 10/23-29/1991.
  34. ** PostScript graphics initially programmed 11/29-30/1992.
  35. ** Last code change made 9/22/1996.
  36. */
  37.  
  38. #include "astrolog.h"
  39.  
  40.  
  41. /*
  42. ******************************************************************************
  43. ** Single Chart Display Routines.
  44. ******************************************************************************
  45. */
  46.  
  47.  
  48. /* Print header info showing time and date of the chart being displayed.   */
  49. /* This is used by ChartListing() and the -l sector chart in PrintChart(). */
  50.  
  51. void PrintHeader()
  52. {
  53.   char sz[cchSzDef];
  54.   int day, fNam, fLoc;
  55.  
  56.   fNam = *ciMain.nam > chNull; fLoc = *ciMain.loc > chNull;
  57.   AnsiColor(kWhite);
  58.   sprintf(sz, "%s %s chart ", szAppName, szVersionCore); PrintSz(sz);
  59.   if (fNoTimeOrSpace)
  60.     PrintSz("(No time or space)\n");
  61.   else if (us.nRel == rcComposite)
  62.     PrintSz("(Composite)\n");
  63.   else {
  64.     sprintf(sz, "for %s%s", ciMain.nam, fNam ? "\n" : ""); PrintSz(sz);
  65.     day = DayOfWeek(Mon, Day, Yea);
  66.     sprintf(sz, "%c%c%c %s %s (%cT %s GMT)", chDay3(day),
  67.       SzDate(Mon, Day, Yea, 3), SzTim(Tim), ChDst(Dst),
  68.       SzZone(Zon)); PrintSz(sz);
  69.     sprintf(sz, "%c%s%s%s\n", fLoc && !fNam ? '\n' : ' ', ciMain.loc,
  70.       fLoc ? " " : "", SzLocation(Lon, Lat)); PrintSz(sz);
  71.   }
  72. }
  73.  
  74.  
  75. /* Print the straight listing of planet and house positions and specified */
  76. /* by the -v switch, along with the element table, etc.                   */
  77.  
  78. void ChartListing()
  79. {
  80.   ET et;
  81.   char sz[cchSzDef];
  82.   int i, j, k, fNam, fLoc;
  83.   real rT;
  84.  
  85.   CreateElemTable(&et);
  86.   fNam = *ciMain.nam > chNull; fLoc = *ciMain.loc > chNull;
  87.  
  88.   PrintHeader();    /* Show time and date of the chart being displayed. */
  89.  
  90. #ifdef INTERPRET
  91.   if (us.fInterpret) {          /* Print an interpretation if -I in effect. */
  92.     if (us.nRel == rcSynastry)
  93.       InterpretSynastry();      /* Print synastry interpretaion for -r -I.  */
  94.     else
  95.       InterpretLocation();      /* Do normal interpretation for just -v -I. */
  96.     return;
  97.   }
  98. #endif
  99.  
  100.   AnsiColor(kDkGray);
  101.   if (us.fSeconds) {
  102.     sprintf(sz, "Body  Location   Ret. %s Rul.      House  Rul. Velocity\n",
  103.       us.fEquator ? "Declin. " : "Latitude"); PrintSz(sz);
  104.   } else {
  105.     sprintf(sz,
  106.       "Body  Locat. Ret. %s. Rul.      House  Rul. Veloc.    %s Houses.\n",
  107.       us.fEquator ? "Decl" : "Lati", szSystem[us.nHouseSystem]); PrintSz(sz);
  108.   }
  109.   if (!fNam && !fLoc)
  110.     PrintL();
  111.  
  112.   /* Ok, now print out the location of each object. */
  113.  
  114.   for (i = 1-us.fSeconds, j = 0; i <= oNorm; i++, j++) {
  115.     if (us.fSeconds) {
  116.       if (FIgnore(i))
  117.         continue;
  118.     } else {
  119.       if (i > oCore && (i <= cuspHi || FIgnore(i)))
  120.         continue;
  121.       while (i <= oCore && j <= oCore && FIgnore(j))
  122.         j++;
  123.     }
  124.     if (i <= oCore && j > oCore)
  125.       PrintTab(' ', 51);
  126.     else {
  127.       if (i > oCore)
  128.         j = i;
  129.       AnsiColor(kObjA[j]);
  130.       sprintf(sz, "%-4.4s: ", szObjName[j]); PrintSz(sz);
  131.       PrintZodiac(planet[j]);
  132.       sprintf(sz, " %c ", ret[j] >= 0.0 ? ' ' : chRet); PrintSz(sz);
  133.       if (j <= cThing || j > cuspHi)
  134.         PrintAltitude(planetalt[j]);
  135.       else
  136.         PrintTab('_', us.fSeconds ? 10 : 7);
  137.       sprintf(sz, " (%c)", Dignify(j, SFromZ(planet[j])));
  138.       PrintSz(FCusp(j) ? "    " : sz);
  139.       k = inhouse[j];
  140.       AnsiColor(kSignA(k));
  141.       sprintf(sz, " [%2d%s house] ", k, szSuffix[k]); PrintSz(sz);
  142.       AnsiColor(kDefault);
  143.       sprintf(sz, "[%c] ", Dignify(j, k)); PrintSz(FCusp(j) ? "    " : sz);
  144.       if ((j != oMoo || us.fPlacalc) &&
  145.         (FObject(j) || ((j == oNod || j == oLil) && us.fPlacalc))) {
  146.         PrintCh((char)(ret[i] < 0.0 ? '-' : '+'));
  147.         rT = DFromR(RAbs(ret[j]));
  148.         sprintf(sz, us.fSeconds ? (rT < 10.0 ? "%9.7f" : "%9.6f") :
  149.           (rT < 10.0 ? "%5.3f" : "%5.2f"), rT); PrintSz(sz);
  150.       } else
  151.         PrintTab('_', us.fSeconds ? 10 : 6);
  152.     }
  153.     if (!us.fSeconds) {
  154.  
  155.       /* For some lines, we have to append the house cusp positions. */
  156.  
  157.       if (i <= cSign) {
  158.         PrintSz("  -  ");
  159.         AnsiColor(kSignA(i));
  160.         sprintf(sz, "House cusp %2d: ", i); PrintSz(sz);
  161.         PrintZodiac(chouse[i]);
  162.       }
  163.  
  164.       /* For some lines, we have to append the element table information. */
  165.  
  166.       if (i == cSign+2)
  167.         PrintSz("     Car Fix Mut TOT");
  168.       else if (i > cSign+2 && i < cSign+7) {
  169.         k = i-(cSign+2)-1;
  170.         AnsiColor(kElemA[k]);
  171.         sprintf(sz, "  %c%c%c%3d %3d %3d %3d",
  172.           szElem[k][0], szElem[k][1], szElem[k][2],
  173.           et.coElemMode[k][0], et.coElemMode[k][1], et.coElemMode[k][2],
  174.           et.coElem[k]); PrintSz(sz);
  175.         AnsiColor(kDefault);
  176.       } else if (i == cSign+7) {
  177.         sprintf(sz, "  TOT %2d %3d %3d %3d",
  178.           et.coMode[0], et.coMode[1], et.coMode[2], et.coSum); PrintSz(sz);
  179.       } else if (i == oCore)
  180.         PrintTab(' ', 23);
  181.       else if (i >= uranLo) {
  182.         sprintf(sz, "  Uranian #%d", i-uranLo+1); PrintSz(sz);
  183.       }
  184.       sz[0] = chNull;
  185.       switch (i-cSign-1) {
  186.       case 1: sprintf(sz, "   +:%2d", et.coYang);  break;
  187.       case 2: sprintf(sz, "   -:%2d", et.coYin);   break;
  188.       case 3: sprintf(sz, "   M:%2d", et.coMC);    break;
  189.       case 4: sprintf(sz, "   N:%2d", et.coIC);    break;
  190.       case 5: sprintf(sz, "   A:%2d", et.coAsc);   break;
  191.       case 6: sprintf(sz, "   D:%2d", et.coDes);   break;
  192.       case 7: sprintf(sz,    "<:%2d", et.coLearn); break;
  193.       }
  194.       PrintSz(sz);
  195.     } else {
  196.       PrintSz(" Decan: ");
  197.       is.fSeconds = fFalse;
  198.       PrintZodiac(Decan(planet[i]));
  199.       is.fSeconds = us.fSeconds;
  200.     }
  201.     PrintL();
  202.   }
  203.  
  204.   /* Do another loop to print out the stars in their specified order. */
  205.  
  206.   if (us.nStar) for (i = starLo; i <= starHi; i++) {
  207.     j = oNorm+starname[i-oNorm];
  208.     if (ignore[j])
  209.       continue;
  210.     AnsiColor(kObjA[j]);
  211.     sprintf(sz, "%-4.4s: ", szObjName[j]); PrintSz(sz);
  212.     PrintZodiac(planet[j]);
  213.     PrintSz("   ");
  214.     PrintAltitude(planetalt[j]);
  215.     k = inhouse[j];
  216.     AnsiColor(kSignA(k));
  217.     sprintf(sz, "     [%2d%s house]", k, szSuffix[k]); PrintSz(sz);
  218.     AnsiColor(kDefault);
  219.     sprintf(sz, "     ______%s Star #%2d: %5.2f\n",
  220.       us.fSeconds ? "____" : " ", i-oNorm, rStarBright[j-oNorm]); PrintSz(sz);
  221.   }
  222. }
  223.  
  224.  
  225. /* Print out the aspect and midpoint grid for a chart, as specified with the */
  226. /* -g switch. (Each grid row takes up 4 lines of text.)                      */
  227.  
  228. void ChartGrid()
  229. {
  230.   char sz[cchSzDef];
  231.   int x, y, r, x1, y1, temp;
  232.  
  233. #ifdef INTERPRET
  234.   if (us.fInterpret) {    /* Print interpretation instead if -I in effect. */
  235.     InterpretGrid();
  236.     return;
  237.   }
  238. #endif
  239.  
  240.   for (y1 = 0, y = 1; y <= cObj; y++) if (!ignore[y])
  241.     for (r = 1; r <= 4; r++) {
  242.       for (x1 = 0, x = 1; x <= cObj; x++) if (!ignore[x]) {
  243.         if (y1 > 0 && x1 > 0 && y+r > 2)
  244.           PrintCh((char)(r > 1 ? chV : chC));
  245.         if (r > 1) {
  246.           temp = grid->n[x][y];
  247.  
  248.           /* Print aspect rows. */
  249.  
  250.           if (x < y) {
  251.             if (temp)
  252.               AnsiColor(kAspA[temp]);
  253.             if (r == 2)
  254.               PrintSz(temp ? szAspectAbbrev[temp] : "   ");
  255.             else if (!temp)
  256.               PrintSz("   ");
  257.             else {
  258.               if (r == 3) {
  259.                 if (grid->v[x][y] < 6000)
  260.                   sprintf(sz, "%c%2d", us.fAppSep ?
  261.                     (grid->v[x][y] < 0 ? 'a' : 's') :
  262.                     (grid->v[x][y] < 0 ? '-' : '+'), abs(grid->v[x][y])/60);
  263.                 else
  264.                   sprintf(sz, "%3d", abs(grid->v[x][y])/60);
  265.               } else
  266.                 sprintf(sz, "%02d'", abs(grid->v[x][y])%60);
  267.               PrintSz(sz);
  268.             }
  269.  
  270.           /* Print midpoint rows. */
  271.  
  272.           } else if (x > y) {
  273.             AnsiColor(kSignA(temp));
  274.             if (r == 2) {
  275.               temp = grid->n[x][y];
  276.               sprintf(sz, "%c%c%c", chSig3(temp));
  277.             } else if (r == 3) {
  278.               sprintf(sz, "%2d%c", grid->v[x][y]/60, chDeg0);
  279.             } else
  280.               sprintf(sz, "%02d'", grid->v[x][y]%60);
  281.             PrintSz(sz);
  282.  
  283.           /* Print the diagonal of object names. */
  284.  
  285.           } else {
  286.             AnsiColor(kReverse);
  287.             if (r == 2) {
  288.               AnsiColor(kObjA[y]);
  289.               sprintf(sz, "%c%c%c", chObj3(y));
  290.             } else {
  291.               temp = SFromZ(planet[y]);
  292.               AnsiColor(kSignA(temp));
  293.               if (r == 3)
  294.                 sprintf(sz, "%2d%c", (int)planet[y] - (temp-1)*30, chDeg0);
  295.               else
  296.                 sprintf(sz, "%c%c%c", chSig3(temp));
  297.             }
  298.             PrintSz(sz);
  299.           }
  300.           AnsiColor(kDefault);
  301.         } else
  302.           if (y1 > 0)
  303.             PrintTab(chH, 3);
  304.         x1++;
  305.       }
  306.       if (y+r > 2)
  307.         PrintL();
  308.       y1++;
  309.     }
  310.   if (y1 == 0)
  311.     PrintSz("Empty aspect grid.\n");
  312. }
  313.  
  314.  
  315. /* This is a subprocedure of DisplayGrands(). Here we print out one aspect */
  316. /* configuration found by the parent procedure.                            */
  317.  
  318. void PrintGrand(ac, i1, i2, i3, i4)
  319. char ac;
  320. int i1, i2, i3, i4;
  321. {
  322.   char sz[cchSzDef];
  323.   int asp;
  324.  
  325.   switch (ac) {
  326.   case acS : asp = aCon; break;
  327.   case acGT: asp = aTri; break;
  328.   case acTS: asp = aOpp; break;
  329.   case acY : asp = aInc; break;
  330.   case acGC: asp = aSqu; break;
  331.   case acC : asp = aSex; break;
  332.   default: ;
  333.   }
  334.   AnsiColor(kAspA[asp]);
  335.   sprintf(sz, "%-11s", szAspectConfig[ac]); PrintSz(sz);
  336.   AnsiColor(kDefault);
  337.   sprintf(sz, " %s ",
  338.     ac == acS || ac == acGT || ac == acGC ? "with" : "from"); PrintSz(sz);
  339.   AnsiColor(kObjA[i1]);
  340.   sprintf(sz, "%c%c%c: ", chObj3(i1)); PrintSz(sz);
  341.   PrintZodiac(planet[i1]);
  342.   sprintf(sz, " %s ", ac == acS || ac == acGT ? "and" : "to "); PrintSz(sz);
  343.   AnsiColor(kObjA[i2]);
  344.   sprintf(sz, "%c%c%c: ", chObj3(i2)); PrintSz(sz);
  345.   PrintZodiac(planet[i2]);
  346.   sprintf(sz, " %s ", ac == acGC || ac == acC ? "to " : "and"); PrintSz(sz);
  347.   AnsiColor(kObjA[i3]);
  348.   sprintf(sz, "%c%c%c: ", chObj3(i3)); PrintSz(sz);
  349.   PrintZodiac(planet[i3]);
  350.   if (ac == acGC || ac == acC) {
  351.     PrintSz(" to ");
  352.     AnsiColor(kObjA[i4]);
  353.     sprintf(sz, "%c%c%c: ", chObj3(i4)); PrintSz(sz);
  354.     PrintZodiac(planet[i4]);
  355.   }
  356.   PrintL();
  357. }
  358.  
  359.  
  360. /* Scan the aspect grid of a chart and print out any major configurations, */
  361. /* as specified with the -g0 switch.                                       */
  362.  
  363. void DisplayGrands()
  364. {
  365.   int cac = 0, i, j, k, l;
  366.  
  367.   for (i = 0; i <= cObj; i++) if (!FIgnore(i))
  368.     for (j = 0; j <= cObj; j++) if (j != i && !FIgnore(j))
  369.       for (k = 0; k <= cObj; k++) if (k != i && k != j && !FIgnore(k)) {
  370.  
  371.         /* Is there a Stellium among the current three planets? */
  372.  
  373.         if (i < j && j < k && grid->n[i][j] == aCon &&
  374.             grid->n[i][k] == aCon && grid->n[j][k] == aCon) {
  375.           cac++;
  376.           PrintGrand(acS, i, j, k, l);
  377.  
  378.         /* Is there a Grand Trine? */
  379.  
  380.         } else if (i < j && j < k && grid->n[i][j] == aTri &&
  381.             grid->n[i][k] == aTri && grid->n[j][k] == aTri) {
  382.           cac++;
  383.           PrintGrand(acGT, i, j, k, l);
  384.  
  385.         /* Is there a T-Square? */
  386.  
  387.         } else if (j < k && grid->n[j][k] == aOpp &&
  388.             grid->n[Min(i, j)][Max(i, j)] == aSqu &&
  389.             grid->n[Min(i, k)][Max(i, k)] == aSqu) {
  390.           cac++;
  391.           PrintGrand(acTS, i, j, k, l);
  392.  
  393.         /* Is there a Yod? */
  394.  
  395.         } else if (j < k && grid->n[j][k] == aSex &&
  396.             grid->n[Min(i, j)][Max(i, j)] == aInc &&
  397.             grid->n[Min(i, k)][Max(i, k)] == aInc) {
  398.           cac++;
  399.           PrintGrand(acY, i, j, k, l);
  400.         }
  401.         for (l = 0; l <= cObj; l++) if (!FIgnore(l)) {
  402.  
  403.           /* Is there a Grand Cross among the current four planets? */
  404.  
  405.           if (i < j && i < k && i < l && j < l && grid->n[i][j] == aSqu &&
  406.               grid->n[Min(j, k)][Max(j, k)] == aSqu &&
  407.               grid->n[Min(k, l)][Max(k, l)] == aSqu &&
  408.               grid->n[i][l] == aSqu &&
  409.               MinDistance(planet[i], planet[k]) > 150.0 &&
  410.               MinDistance(planet[j], planet[l]) > 150.0) {
  411.             cac++;
  412.             PrintGrand(acGC, i, j, k, l);
  413.  
  414.           /* Is there a Cradle? */
  415.  
  416.           } else if (i < l && grid->n[Min(i, j)][Max(i, j)] == aSex &&
  417.               grid->n[Min(j, k)][Max(j, k)] == aSex &&
  418.               grid->n[Min(k, l)][Max(k, l)] == aSex &&
  419.               MinDistance(planet[i], planet[l]) > 150.0) {
  420.             cac++;
  421.             PrintGrand(acC, i, j, k, l);
  422.           }
  423.         }
  424.       }
  425.   if (!cac)
  426.     PrintSz("No major configurations in aspect grid.\n");
  427. }
  428.  
  429.  
  430. /* This is subprocedure of ChartWheel(). Here we print out the location */
  431. /* of a particular house cusp as well as what house cusp number it is.  */
  432.  
  433. void PrintHouse(i, left)
  434. int i, left;
  435. {
  436.   char sz[cchSzDef];
  437.  
  438.   if (!left)
  439.     PrintZodiac(chouse[i]);
  440.   AnsiColor(kSignA(i));
  441.   sprintf(sz, "<%d>", i); PrintSz(sz);
  442.   if (left)
  443.     PrintZodiac(chouse[i]);
  444.   else
  445.     AnsiColor(kDefault);
  446. }
  447.  
  448.  
  449. /* Another subprocedure of ChartWheel(). Print out one of the chart info */
  450. /* rows in the middle of the wheel (which may be blank) given an index.  */
  451.  
  452. void PrintWheelCenter(irow)
  453. int irow;
  454. {
  455.   char sz[cchSzDef], szT[8];
  456.   int cch, nT;
  457.  
  458.   if (*ciMain.nam == chNull && *ciMain.loc == chNull)    /* Try to center */
  459.     irow--;
  460.   if (*ciMain.nam == chNull && irow >= 1)    /* Don't have blank lines if */
  461.     irow++;                                  /* the name and/or location  */
  462.   if (*ciMain.loc == chNull && irow >= 3)    /* strings are empty.        */
  463.     irow++;
  464.   switch (irow) {
  465.   case 0:
  466.     sprintf(sz, "%s %s chart", szAppName, szVersionCore);
  467.     break;
  468.   case 1:
  469.     sprintf(sz, "%s", ciMain.nam);
  470.     break;
  471.   case 2:
  472.     nT = DayOfWeek(Mon, Day, Yea);
  473.     sprintf(sz, "%c%c%c %s %s", chDay3(nT), SzDate(Mon, Day, Yea, 2),
  474.       SzTim(Tim));
  475.     break;
  476.   case 3:
  477.     sprintf(sz, "%s", ciMain.loc);
  478.     break;
  479.   case 4:
  480.     nT = (int)(RFract(RAbs(Zon))*100.0+rRound);
  481.     sprintf(sz, "%cT %c%02d:%02d, %s", ChDst(Dst),
  482.       Zon > 0.0 ? '-' : '+', (int)RAbs(Zon), nT, SzLocation(Lon, Lat));
  483.     break;
  484.   case 5:
  485.     nT = us.fEuroTime; us.fEuroTime = fTrue;
  486.     sprintf(szT, "%s", SzTim(DegToDec(DFromR(is.RA)*(24.0/rDegMax))));
  487.     sprintf(sz, "UT: %s, Sid.T: %s", SzTim(Tim+Zon-Dst), szT);
  488.     us.fEuroTime = nT;
  489.     break;
  490.   case 6:
  491.     sprintf(sz, "%s Houses", szSystem[us.nHouseSystem]);
  492.     break;
  493.   case 7:
  494.     sprintf(sz, "%s / %s", us.fSidereal ? "Sidereal" : "Tropical",
  495.       us.objCenter == oSun ? "Heliocentric" :
  496.       (us.objCenter == oEar ? "Geocentric" : szObjName[us.objCenter]));
  497.     break;
  498.   case 8:
  499.     sprintf(sz, "Julian Day = %12.4f", JulianDayFromTime(is.T));
  500.     break;
  501.   default:
  502.     *sz = chNull;
  503.   }
  504.   cch = CchSz(sz);
  505.   nT = WHEELCOLS*2-1 + is.fSeconds*8;
  506.   PrintTab(' ', (nT - cch) / 2);
  507.   PrintSz(sz);
  508.   PrintTab(' ', nT-cch - (nT - cch) / 2);
  509. }
  510.  
  511.  
  512. /* Yet another subprocedure of ChartWheel(). Here we print out one line */
  513. /* in a particular house cell (which may be blank).                     */
  514.  
  515. void PrintWheelSlot(obj)
  516. int obj;
  517. {
  518.   char sz[cchSzDef];
  519.  
  520.   if (obj >= oEar) {
  521.     AnsiColor(kObjA[obj]);
  522.     sprintf(sz, " %c%c%c ", chObj3(obj)); PrintSz(sz);
  523.     PrintZodiac(planet[obj]);
  524.     sprintf(sz, "%c ", ret[obj] < 0.0 ? 'r' : ' '); PrintSz(sz);
  525.     PrintTab(' ', WHEELCOLS-15);
  526.   } else                            /* This particular line is blank. */
  527.     PrintTab(' ', WHEELCOLS-1 + is.fSeconds*4);
  528. }
  529.  
  530.  
  531. /* Display all the objects in a wheel format on the screen, as specified */
  532. /* with the -w switch. The wheel is divided into the 12 houses and the   */
  533. /* planets are placed accordingly.                                       */
  534.  
  535. void ChartWheel()
  536. {
  537.   int wheel[cSign][WHEELROWS], wheelcols, count = 0, i, j, k, l;
  538.  
  539.   /* If the seconds (-b0) flag is set, we'll print all planet and house    */
  540.   /* locations to the nearest zodiac second instead of just to the minute. */
  541.  
  542.   wheelcols = WHEELCOLS + is.fSeconds*4;
  543.  
  544.   for (i = 0; i < cSign; i++)
  545.     for (j = 0; j < us.nWheelRows; j++)
  546.       wheel[i][j] = -1;                    /* Clear out array. */
  547.  
  548.   /* This section of code places each object in the wheel house array. */
  549.  
  550.   for (i = 0; i <= cObj && count < us.nWheelRows*12; i++) {
  551.     if (FIgnore(i) || (FCusp(i) &&
  552.       MinDistance(planet[i], chouse[i-oAsc+1]) < rRound/60.0))
  553.       continue;
  554.  
  555.     /* Try to put object in its proper house. If no room, */
  556.     /* then overflow over to the next succeeding house.   */
  557.  
  558.     for (j = inhouse[i]-1; j < cSign; j = j < cSign ? (j+1)%cSign : j) {
  559.  
  560.       /* Now try to find the proper place in the house to put the object. */
  561.       /* This is in sorted order, although a check is made for 0 Aries.   */
  562.  
  563.       if (wheel[j][us.nWheelRows-1] >= 0)
  564.         continue;
  565.       l = chouse[j+1] > chouse[Mod12(j+2)];
  566.       for (k = 0; wheel[j][k] >= 0 && (planet[i] >= planet[wheel[j][k]] ||
  567.          (l && planet[i] < rDegHalf && planet[wheel[j][k]] > rDegHalf)) &&
  568.         !(l && planet[i] > rDegHalf && planet[wheel[j][k]] < rDegHalf); k++)
  569.         ;
  570.  
  571.       /* Actually insert object in proper place. */
  572.  
  573.       if (wheel[j][k] < 0)
  574.         wheel[j][k] = i;
  575.       else {
  576.         for (l = us.nWheelRows-1; l > k; l--)
  577.           wheel[j][l] = wheel[j][l-1];
  578.         wheel[j][k] = i;
  579.       }
  580.       count++;
  581.       j = cSign;
  582.     }
  583.   }
  584.  
  585.   /* Now, if this is really the -w switch and not -w0, then reverse the */
  586.   /* order of objects in western houses for more intuitive reading.     */
  587.  
  588.   if (!us.fWheelReverse)
  589.     for (i = 3; i < 9; i++)
  590.       for (j = 0; j < us.nWheelRows/2; j++) {
  591.         k = us.nWheelRows-1-j;
  592.         l = wheel[i][j]; wheel[i][j] = wheel[i][k]; wheel[i][k] = l;
  593.       }
  594.  
  595.   /* Here we actually print the wheel and the objects in it. */
  596.  
  597.   PrintCh(chNW); PrintTab(chH, WHEELCOLS-8); PrintHouse(11, fTrue);
  598.   PrintTab(chH, WHEELCOLS-11); PrintHouse(10, fTrue);
  599.   PrintTab(chH, WHEELCOLS-10); PrintHouse(9, fTrue);
  600.   PrintTab(chH, wheelcols-4); PrintCh(chNE); PrintL();
  601.   for (i = 0; i < us.nWheelRows; i++) {
  602.     for (j = 10; j >= 7; j--) {
  603.       PrintCh(chV); PrintWheelSlot(wheel[j][i]);
  604.     }
  605.     PrintCh(chV); PrintL();
  606.   }
  607.   PrintHouse(12, fTrue); PrintTab(chH, WHEELCOLS-11);
  608.   PrintCh(chC); PrintTab(chH, wheelcols-1); PrintCh(chJN);
  609.   PrintTab(chH, wheelcols-1); PrintCh(chC); PrintTab(chH, WHEELCOLS-10);
  610.   PrintHouse(8, fFalse); PrintL();
  611.   for (i = 0; i < us.nWheelRows; i++) {
  612.     PrintCh(chV); PrintWheelSlot(wheel[11][i]); PrintCh(chV);
  613.     PrintWheelCenter(i);
  614.     PrintCh(chV); PrintWheelSlot(wheel[6][i]);
  615.     PrintCh(chV); PrintL();
  616.   }
  617.   PrintHouse(1, fTrue); PrintTab(chH, WHEELCOLS-10);
  618.   PrintCh(chJW); PrintWheelCenter(us.nWheelRows); PrintCh(chJE);
  619.   PrintTab(chH, WHEELCOLS-10); PrintHouse(7, fFalse); PrintL();
  620.   for (i = 0; i < us.nWheelRows; i++) {
  621.     PrintCh(chV); PrintWheelSlot(wheel[0][i]); PrintCh(chV);
  622.     PrintWheelCenter(us.nWheelRows+1 + i);
  623.     PrintCh(chV); PrintWheelSlot(wheel[5][i]);
  624.     PrintCh(chV); PrintL();
  625.   }
  626.   PrintHouse(2, fTrue); PrintTab(chH, WHEELCOLS-10);
  627.   PrintCh(chC); PrintTab(chH, wheelcols-1); PrintCh(chJS);
  628.   PrintTab(chH, wheelcols-1); PrintCh(chC);
  629.   PrintTab(chH, WHEELCOLS-10); PrintHouse(6, fFalse); PrintL();
  630.   for (i = 0; i < us.nWheelRows; i++) {
  631.     for (j = 1; j <= 4; j++) {
  632.       PrintCh(chV); PrintWheelSlot(wheel[j][i]);
  633.     }
  634.     PrintCh(chV); PrintL();
  635.   }
  636.   PrintCh(chSW); PrintTab(chH, wheelcols-4); PrintHouse(3, fFalse);
  637.   PrintTab(chH, WHEELCOLS-10); PrintHouse(4, fFalse);
  638.   PrintTab(chH, WHEELCOLS-10); PrintHouse(5, fFalse);
  639.   PrintTab(chH, WHEELCOLS-7); PrintCh(chSE); PrintL();
  640. }
  641.  
  642.  
  643. /* This is a subprocedure of ChartAspect() and ChartAspectRelation().       */
  644. /* Display summary information about the aspect list, i.e. the total number */
  645. /* of aspects of each type, and the number of aspects to each object, as    */
  646. /* done when the -a0 aspect summary setting is set.                         */
  647.  
  648. void PrintAspectSummary(ca, co, count, rPowSum)
  649. int *ca, *co, count;
  650. real rPowSum;
  651. {
  652.   char sz[cchSzDef];
  653.   int i, j, k;
  654.  
  655.   if (!us.fAspSummary)
  656.     return;
  657.   if (count == 0) {
  658.     PrintSz("No aspects in list.\n");
  659.     return;
  660.   }
  661.   PrintL();
  662.   sprintf(sz, "Sum power: %.2f - Average power: %.2f\n",
  663.     rPowSum, rPowSum/(real)count); PrintSz(sz);
  664.   k = us.fParallel ? Min(us.nAsp, aOpp) : us.nAsp;
  665.   for (j = 0, i = 1; i <= k; i++) if (!ignorea(i)) {
  666.     if (!(j & 7)) {
  667.       if (j)
  668.         PrintL();
  669.     } else
  670.       PrintSz("   ");
  671.     AnsiColor(kAspA[i]);
  672.     sprintf(sz, "%s:%3d", szAspectAbbrev[i], ca[i]); PrintSz(sz);
  673.     j++;
  674.   }
  675.   PrintL();
  676.   for (j = 0, i = 0; i <= cObj; i++) if (!FIgnore(i)) {
  677.     if (!(j & 7)) {
  678.       if (j)
  679.         PrintL();
  680.     } else
  681.       PrintSz("   ");
  682.     AnsiColor(kObjA[i]);
  683.     sprintf(sz, "%c%c%c:%3d", chObj3(i), co[i]); PrintSz(sz);
  684.     j++;
  685.   }
  686.   PrintL();
  687. }
  688.  
  689.  
  690. /* Display all aspects between objects in the chart, one per line, in       */
  691. /* sorted order based on the total "power" of the aspect, as specified with */
  692. /* the -a switch. The same influences used for -I charts are used here.     */
  693.  
  694. void ChartAspect()
  695. {
  696.   int ca[cAspect + 1], co[objMax];
  697.   char sz[cchSzDef];
  698.   int pcut = 30000, icut, jcut, phi, ihi, jhi, ahi, p, i, j, k, count = 0;
  699.   real ip, jp, rPowSum = 0.0;
  700.  
  701.   ClearB((lpbyte)ca, (cAspect + 1)*(int)sizeof(int));
  702.   ClearB((lpbyte)co, objMax*(int)sizeof(int));
  703.   loop {
  704.     phi = -1;
  705.  
  706.     /* Search for the next most powerful aspect in the aspect grid. */
  707.  
  708.     for (i = 1; i <= cObj; i++) if (!FIgnore(i))
  709.       for (j = 0; j < i; j++) if (!FIgnore(j))
  710.         if (k = grid->n[j][i]) {
  711.           ip = i <= oNorm ? rObjInf[i] : 2.5;
  712.           jp = j <= oNorm ? rObjInf[j] : 2.5;
  713.           p = (int)(rAspInf[k]*(ip+jp)/2.0*
  714.             (1.0-RAbs((real)(grid->v[j][i]))/60.0/GetOrb(i, j, k))*1000.0);
  715.           if ((p < pcut || (p == pcut && (i > icut ||
  716.             (i == icut && j > jcut)))) && p > phi) {
  717.             ihi = i; jhi = j; phi = p; ahi = k;
  718.           }
  719.         }
  720.     if (phi < 0)    /* Exit when no less powerful aspect found. */
  721.       break;
  722.     pcut = phi; icut = ihi; jcut = jhi;
  723.     count++;                               /* Display the current aspect.   */
  724. #ifdef INTERPRET
  725.     if (us.fInterpret) {                   /* Interpret it if -I in effect. */
  726.       InterpretAspect(jhi, ihi);
  727.       continue;
  728.     }
  729. #endif
  730.     rPowSum += (real)phi/1000.0;
  731.     ca[ahi]++;
  732.     co[jhi]++; co[ihi]++;
  733.     sprintf(sz, "%3d: ", count); PrintSz(sz);
  734.     PrintAspect(jhi, SFromZ(planet[jhi]), (int)RSgn(ret[jhi]), ahi,
  735.       ihi, SFromZ(planet[ihi]), (int)RSgn(ret[ihi]), 'a');
  736.     k = grid->v[jhi][ihi];
  737.     AnsiColor(k < 0 ? kWhite : kLtGray);
  738.     sprintf(sz, " - orb: %c%d%c%02d'",
  739.       us.fAppSep ? (k < 0 ? 'a' : 's') : (k < 0 ? '-' : '+'),
  740.       abs(k)/60, chDeg1, abs(k)%60); PrintSz(sz);
  741.     AnsiColor(kDkGreen);
  742.     sprintf(sz, " - power:%6.2f\n", (real)phi/1000.0); PrintSz(sz);
  743.     AnsiColor(kDefault);
  744.   }
  745.  
  746.   PrintAspectSummary(ca, co, count, rPowSum);
  747. }
  748.  
  749.  
  750. /* This is a subprocedure of ChartMidpoint() and ChartMidpointRelation().  */
  751. /* Display summary information about the midpoint list, i.e. the total     */
  752. /* number of midpoints in each sign, and their average span in degrees, as */
  753. /* done when the -m0 midpoint summary setting is set.                      */
  754.  
  755. void PrintMidpointSummary(cs, count, lSpanSum)
  756. int *cs, count;
  757. long lSpanSum;
  758. {
  759.   char sz[cchSzDef];
  760.   int m, i;
  761.  
  762.   if (!us.fMidSummary)
  763.     return;
  764.   if (count == 0) {
  765.     PrintSz("No midpoints in list.\n");
  766.     return;
  767.   }
  768.   PrintL();
  769.   m = (int)(lSpanSum/count);
  770.   sprintf(sz, "Average span:%4d%c%02d'\n", m/60, chDeg1, m%60); PrintSz(sz);
  771.   for (i = 1; i <= cSign; i++) {
  772.     if (i == sLib)
  773.       PrintL();
  774.     else if (i != sAri)
  775.       PrintSz("   ");
  776.     AnsiColor(kSignA(i));
  777.     sprintf(sz, "%c%c%c:%3d", chSig3(i), cs[i]); PrintSz(sz);
  778.   }
  779.   PrintL();
  780. }
  781.  
  782.  
  783. /* Display locations of all midpoints between objects in the chart, */
  784. /* one per line, in sorted zodiac order from zero Aries onward, as  */
  785. /* specified with the -m switch.                                    */
  786.  
  787. void ChartMidpoint()
  788. {
  789.   int cs[cSign + 1];
  790.   char sz[cchSzDef];
  791.   int mcut = -1, icut, jcut, mlo, ilo, jlo, m, i, j, k, count = 0;
  792.   long lSpanSum = 0;
  793.   real l, n, mid;
  794.  
  795.   ClearB((lpbyte)cs, (cSign + 1)*(int)sizeof(int));
  796.   is.fSeconds = fFalse;
  797.   loop {
  798.     mlo = 21600;
  799.  
  800.     /* Search for the next closest midpoint farther down in the zodiac. */
  801.  
  802.     for (i = 0; i < cObj; i++) if (!FIgnore(i))
  803.       for (j = i+1; j <= cObj; j++) if (!FIgnore(j)) {
  804.         m = (grid->n[j][i]-1)*30*60 + grid->v[j][i];
  805.         if ((m > mcut || (m == mcut && (i > icut ||
  806.           (i == icut && j > jcut)))) && m < mlo) {
  807.           ilo = i; jlo = j; mlo = m;
  808.         }
  809.       }
  810.     if (mlo >= 21600)    /* Exit when no midpoint farther in zodiac found. */
  811.       break;
  812.     mcut = mlo; icut = ilo; jcut = jlo;
  813.     count++;                               /* Display the current midpoint. */
  814. #ifdef INTERPRET
  815.     if (us.fInterpret) {                   /* Interpret it if -I in effect. */
  816.       InterpretMidpoint(ilo, jlo);
  817.       continue;
  818.     }
  819. #endif
  820.     cs[mlo/60/30+1]++;
  821.     sprintf(sz, "%4d: ", count); PrintSz(sz);
  822.     mid = (real)mlo/60.0; PrintZodiac(mid);
  823.     PrintCh(' ');
  824.     PrintAspect(ilo, SFromZ(planet[ilo]), (int)RSgn(ret[ilo]), 0,
  825.       jlo, SFromZ(planet[jlo]), (int)RSgn(ret[jlo]), 'm');
  826.     AnsiColor(kDefault);
  827.     m = (int)(MinDistance(planet[ilo], planet[jlo])*60.0);
  828.     lSpanSum += m;
  829.     sprintf(sz, "-%4d%c%02d' degree span.\n", m/60, chDeg1, m%60);
  830.     PrintSz(sz);
  831.  
  832.     /* If the -ma switch is set, determine and display each aspect from one */
  833.     /* of the planets to the current midpoint, and the aspect's orb.        */
  834.  
  835.     if (!us.fMidAspect)
  836.       continue;
  837.     for (i = 0; i < cObj; i++) if (!FIgnore(i)) {
  838.       l = MinDistance(planet[i], mid);
  839.       for (k = us.nAsp; k >= 1; k--) {
  840.         if (!FAcceptAspect(i, k, ilo))
  841.           continue;
  842.         n = l-rAspAngle[k];
  843.         if (RAbs(n) < GetOrb(i, ilo, k)) {
  844.           if (us.fAppSep)
  845.             n = RSgn2((ret[ilo]+ret[jlo])/2.0-ret[i])*
  846.               RSgn2(MinDifference(planet[i], mid))*RSgn2(n)*RAbs(n);
  847.           PrintSz("      Midpoint "); PrintZodiac(mid); PrintSz(" makes ");
  848.           AnsiColor(kAspA[k]); PrintSz(szAspectAbbrev[k]);
  849.           AnsiColor(kDefault); PrintSz(" to ");
  850.           AnsiColor(kObjA[i]); sprintf(sz, "%.10s", szObjName[i]);
  851.           PrintSz(sz);
  852.           PrintTab(' ', 10-CchSz(szObjName[i]));
  853.           j = (int)(n*60.0);
  854.           AnsiColor(j < 0.0 ? kWhite : kLtGray);
  855.           sprintf(sz, "- orb: %c%d%c%02d'",
  856.             us.fAppSep ? (j < 0 ? 'a' : 's') : (j < 0 ? '-' : '+'),
  857.             abs(j)/60, chDeg1, abs(j)%60); PrintSz(sz);
  858.           PrintL();
  859.           AnsiColor(kDefault);
  860.         }
  861.       }
  862.     }
  863.   }
  864.   is.fSeconds = us.fSeconds;
  865.  
  866.   PrintMidpointSummary(cs, count, lSpanSum);
  867. }
  868.  
  869.  
  870. /* Display locations of the objects on the screen with respect to the local */
  871. /* horizon, as specified with the -Z switch.                                */
  872.  
  873. void ChartHorizon()
  874. {
  875.   char sz[cchSzDef], szFormat[cchSzDef];
  876.   real lon, lat, sx, sy, vx, vy,
  877.     lonz[objMax], latz[objMax], azi[objMax], alt[objMax];
  878.   int fPrime, i, j, k, tot;
  879.  
  880.   /* Set up some initial variables. */
  881.  
  882.   fPrime = us.fPrimeVert;
  883.   lon = RFromD(Mod(Lon)); lat = RFromD(Lat);
  884.   tot = us.nStar ? cObj : oNorm;
  885.  
  886.   /* First find zenith location on Earth of each object. */
  887.  
  888.   for (i = 1; i <= tot; i++) if (!ignore[i] || i == oMC) {
  889.     lonz[i] = RFromD(Tropical(planet[i])); latz[i] = RFromD(planetalt[i]);
  890.     EclToEqu(&lonz[i], &latz[i]);
  891.   }
  892.  
  893.   /* Then, convert this to local horizon altitude and azimuth. */
  894.  
  895.   for (i = 1; i <= tot; i++) if (!ignore[i] && i != oMC) {
  896.     lonz[i] = RFromD(Mod(DFromR(lonz[oMC]-lonz[i]+lon)));
  897.     lonz[i] = RFromD(Mod(DFromR(lonz[i]-lon+rPiHalf)));
  898.     EquToLocal(&lonz[i], &latz[i], rPiHalf-lat);
  899.     azi[i] = rDegMax-DFromR(lonz[i]); alt[i] = DFromR(latz[i]);
  900.   }
  901.  
  902.   /* If the -Z0 switch flag is in effect, convert from altitude/azimuth  */
  903.   /* coordinates to prime vertical coordinates that we'll print instead. */
  904.  
  905.   if (fPrime) {
  906.     for (i = 1; i <= tot; i++) if (!ignore[i] && i != oMC) {
  907.       azi[i] = RFromD(azi[i]); alt[i] = RFromD(alt[i]);
  908.       CoorXform(&azi[i], &alt[i], rPiHalf);
  909.       azi[i] = DFromR(azi[i]); alt[i] = DFromR(alt[i]);
  910.     }
  911.   }
  912.  
  913.   /* Now, actually print the location of each object. */
  914.  
  915.   sprintf(szFormat, is.fSeconds ? " " : "");
  916.   sprintf(sz, "Body %s%sAltitude%s %s%sAzimuth%s%s  Azi. Vector%s    ",
  917.     szFormat, szFormat, szFormat, szFormat, szFormat, szFormat, szFormat,
  918.     szFormat); PrintSz(sz);
  919.   sprintf(sz, "%s Vector%s%s    Moon Vector\n\n",
  920.     us.objCenter != oSun ? "Sun" : "Earth", szFormat, szFormat); PrintSz(sz);
  921.   for (k = 1; k <= tot; k++) {
  922.     i = k <= oNorm ? k : oNorm+starname[k-oNorm];
  923.     if (ignore[i] || !FThing(i))
  924.       continue;
  925.     AnsiColor(kObjA[i]);
  926.     sprintf(sz, "%-4.4s: ", szObjName[i]); PrintSz(sz);
  927.     PrintAltitude(alt[i]);
  928.  
  929.     /* Determine directional vector based on azimuth. */
  930.  
  931.     sprintf(sz, " %s", SzDegree(azi[i])); PrintSz(sz);
  932.     sx = RCos(RFromD(azi[i])); sy = RSin(RFromD(azi[i]));
  933.     if (RAbs(sx) < RAbs(sy)) {
  934.       vx = RAbs(sx / sy); vy = 1.0;
  935.     } else {
  936.       vy = RAbs(sy / sx); vx = 1.0;
  937.     }
  938.     sprintf(sz, is.fSeconds ? " (%.3f%c" : " (%.2f%c", vy,
  939.       sy < 0.0 ? (fPrime ? 'u' : 's') : (fPrime ? 'd' : 'n')); PrintSz(sz);
  940.     sprintf(sz, is.fSeconds ? " %.2f%c)" : " %.2f%c)", vx,
  941.       sx > 0.0 ? 'e' : 'w'); PrintSz(sz);
  942.  
  943.     /* Determine distance vector of current object from Sun and Moon. */
  944.  
  945.     vx = azi[1]-azi[i]; vy = azi[2]-azi[i];
  946.     j = 1 + is.fSeconds;
  947.     sprintf(szFormat, " [%%%d.%df%%%d.%df] [%%%d.%df%%%d.%df]",
  948.       j+5, j, j+5, j, j+5, j, j+5, j);
  949.     sprintf(sz, szFormat,
  950.       RAbs(vx) < rDegHalf ? vx : RSgn(vx)*(rDegMax-RAbs(vx)), alt[1]-alt[i],
  951.       RAbs(vy) < rDegHalf ? vy : RSgn(vy)*(rDegMax-RAbs(vy)), alt[2]-alt[i]);
  952.     PrintSz(sz);
  953.     if (!is.fSeconds && i >= uranLo) {
  954.       if (i <= uranHi)
  955.         sprintf(sz, "  Uranian #%d", i-uranLo+1);
  956.       else
  957.         sprintf(sz, "  Star #%2d", i-starLo+1);
  958.       PrintSz(sz);
  959.     }
  960.     PrintL();
  961.   }
  962.   AnsiColor(kDefault);
  963. }
  964.  
  965.  
  966. /* Display x,y,z locations of each body (in AU) with respect to the Sun */
  967. /* (or whatever the specified center planet is), as in the -S switch.   */
  968. /* These values were already determined when calculating the planet     */
  969. /* positions themselves, so this procedure is basically just a loop.    */
  970.  
  971. void ChartOrbit()
  972. {
  973.   char sz[cchSzDef], szFormat[cchSzDef];
  974.   real x, y, z;
  975.   int i;
  976.  
  977.   sprintf(szFormat, is.fSeconds ? " " : "");
  978.   sprintf(sz, "Body%s    Angle%s%s%s%s    ",
  979.     szFormat, szFormat, szFormat, szFormat, szFormat);
  980.   PrintSz(sz);
  981.   sprintf(sz,
  982.     "%sX axis%s%s%s    %sY axis%s%s%s    %sZ axis%s%s%s    %sLength\n",
  983.     szFormat, szFormat, szFormat, szFormat, szFormat, szFormat, szFormat,
  984.     szFormat, szFormat, szFormat, szFormat, szFormat, szFormat);
  985.   PrintSz(sz);
  986.   for (i = 0; i <= oNorm; i++) {
  987.     if (ignore[i] || (!FThing(i) ||
  988.       ((i == oMoo || i == oNod || i == oSou) && !us.fPlacalc)))
  989.       continue;
  990.     AnsiColor(kObjA[i]);
  991.     sprintf(sz, "%c%c%c%c: ", chObj3(i),
  992.       szObjName[i][3] ? szObjName[i][3] : ' '); PrintSz(sz);
  993.     x = spacex[i]; y = spacey[i]; z = spacez[i];
  994.     sprintf(sz, is.fSeconds ? "[%11.7f] [%11.7f] [%11.7f] [%11.7f] [%11.7f]" :
  995.       "[%7.3f] [%7.3f] [%7.3f] [%7.3f] [%7.3f]",
  996.       planet[i], x, y, z, RSqr(x*x+y*y+z*z)); PrintSz(sz);
  997.     if (!is.fSeconds && i >= uranLo) {
  998.       sprintf(sz, "  Uranian #%d", i-uranLo+1); PrintSz(sz);
  999.     }
  1000.     PrintL();
  1001.   }
  1002.   AnsiColor(kDefault);
  1003. }
  1004.  
  1005.  
  1006. /* Display locations of the planets on the screen with respect to the 36    */
  1007. /* Gauquelin sectors and their plus zones, as specified with the -l switch. */
  1008.  
  1009. void ChartSector()
  1010. {
  1011.   char sz[cchSzDef];
  1012.   CP cp;
  1013.   int c[cSector + 1], i, sec, pls, kPls, cpls = 0, co = 0, cq = 0;
  1014.   real r, rT;
  1015.  
  1016.   for (i = 1; i <= cSector; i++) {
  1017.     c[i] = 0;
  1018.     cpls += pluszone[i];
  1019.   }
  1020.   cp = cp0;
  1021.   CastSectors();
  1022.  
  1023.   AnsiColor(kDkGray);
  1024.   PrintSz("Body  Sector ");
  1025.   if (is.fSeconds)
  1026.     PrintSz(
  1027.       "  Plus      House   Sign Loc. Ret. Latitude Velocity Sec.18 Sec.12\n");
  1028.   else
  1029.     PrintSz("Plus    House   Sign Ret. Latit. Veloc. 18 12\n");
  1030.   for (i = 0; i <= cObj; i++) {
  1031.     if (FIgnore(i) || !FThing(i))
  1032.       continue;
  1033.     co++;
  1034.     AnsiColor(kObjA[i]);
  1035.     sprintf(sz, "%c%c%c%c: ", chObj3(i),
  1036.       szObjName[i][3] ? szObjName[i][3] : ' '); PrintSz(sz);
  1037.     r = (rDegMax - planet[i])/10.0;
  1038.     sec = (int)r + 1; c[sec]++;
  1039.     pls = pluszone[sec];
  1040.     cq += pls;
  1041.     kPls = (pls ? kRainbowA[1] : kMainA[5]);
  1042.     AnsiColor(kDkGray);
  1043.     PrintSz("Sec");
  1044.     AnsiColor(kPls);
  1045.     sprintf(sz, " %2d", sec); PrintSz(sz);
  1046.     if (is.fSeconds) {
  1047.       AnsiColor(kDkGray);
  1048.       sprintf(sz, "%.3f", RFract(r)); PrintSz(&sz[1]);
  1049.       AnsiColor(kPls);
  1050.     }
  1051.     sprintf(sz, " %c", (char)(pls ? '+' : '-')); PrintSz(sz);
  1052.     AnsiColor(kSignA(cp.house[i]));
  1053.     sprintf(sz, " [%2d%s house] ", cp.house[i], szSuffix[cp.house[i]]);
  1054.     PrintSz(sz);
  1055.     PrintZodiac(cp.obj[i]);
  1056.     sprintf(sz, " %c ", cp.dir[i] < 0.0 ? chRet : ' '); PrintSz(sz);
  1057.     PrintAltitude(cp.alt[i]);
  1058.     PrintCh(' ');
  1059.     if ((i != oMoo || us.fPlacalc) &&
  1060.       (FObject(i) || ((i == oNod || i == oLil) && us.fPlacalc))) {
  1061.       PrintCh((char)(ret[i] < 0.0 ? '-' : '+'));
  1062.       rT = DFromR(RAbs(ret[i]));
  1063.       sprintf(sz, is.fSeconds ? (rT < 10.0 ? "%7.5f" : "%7.4f") :
  1064.         (rT < 10.0 ? "%5.3f" : "%5.2f"), rT); PrintSz(sz);
  1065.     } else
  1066.       PrintTab('_', us.fSeconds ? 8 : 6);
  1067.     AnsiColor(kPls);
  1068.     sprintf(sz, " %2d", (sec-1)/2 + 1); PrintSz(sz);
  1069.     if (is.fSeconds) {
  1070.       AnsiColor(kDkGray);
  1071.       sprintf(sz, "%.3f", RFract(r/2.0)); PrintSz(&sz[1]);
  1072.     }
  1073.     AnsiColor(kPls);
  1074.     sprintf(sz, " %2d", (sec-1)/3 + 1); PrintSz(sz);
  1075.     if (is.fSeconds) {
  1076.       AnsiColor(kDkGray);
  1077.       sprintf(sz, "%.3f", RFract(r/3.0)); PrintSz(&sz[1]);
  1078.     }
  1079.     PrintL();
  1080.   }
  1081.  
  1082.   /* Display summary information, i.e. the planet in plus zone ratio. */
  1083.  
  1084.   AnsiColor(kDefault);
  1085.   sprintf(sz, "\nPlus zones: %d/%d = %.2f%% - ", cpls, cSector,
  1086.     (real)cpls/(real)36*100.0); PrintSz(sz);
  1087.   sprintf(sz, "Planets in plus zones: %d/%d = %.2f%%\n", cq, co,
  1088.     co ? (real)cq/(real)co*100.0 : 0.0); PrintSz(sz);
  1089.  
  1090.   /* Display more summary information, i.e. the number of planets in each */
  1091.   /* sector, as well as whether each sector is a plus zone or not.        */
  1092.  
  1093.   PrintSz("\nZone:");
  1094.   for (i = 1; i <= cSector/2; i++) {
  1095.     pls = pluszone[i];
  1096.     AnsiColor(pls ? kRainbowA[1] : kMainA[5]);
  1097.     sprintf(sz, " %2d%c", i, pls ? '+' : '-'); PrintSz(sz);
  1098.   }
  1099.   AnsiColor(kDefault);
  1100.   PrintSz("\nNum :");
  1101.   for (i = 1; i <= cSector/2; i++) {
  1102.     if (c[i]) {
  1103.       sprintf(sz, " %2d ", c[i]); PrintSz(sz);
  1104.     } else
  1105.       PrintSz("  . ");
  1106.   }
  1107.   PrintSz("\nZone:");
  1108.   for (i = cSector; i > cSector/2; i--) {
  1109.     pls = pluszone[i];
  1110.     AnsiColor(pls ? kRainbowA[1] : kMainA[5]);
  1111.     sprintf(sz, " %2d%c", i, pls ? '+' : '-'); PrintSz(sz);
  1112.   }
  1113.   AnsiColor(kDefault);
  1114.   PrintSz("\nNum :");
  1115.   for (i = cSector; i > cSector/2; i--) {
  1116.     if (c[i]) {
  1117.       sprintf(sz, " %2d ", c[i]); PrintSz(sz);
  1118.     } else
  1119.       PrintSz("  . ");
  1120.   }
  1121.   PrintL();
  1122.   CastChart(fTrue);
  1123. }
  1124.  
  1125.  
  1126. /* Print the locations of the astro-graph lines on the Earth as specified */
  1127. /* with the -L switch. This includes Midheaven and Nadir lines, zenith    */
  1128. /* positions, and locations of Ascendant and Descendant lines.            */
  1129.  
  1130. void ChartAstroGraph()
  1131. {
  1132.   CrossInfo FPTR *c;
  1133.   char sz[cchSzDef];
  1134.   real planet1[objMax], planet2[objMax], mc[objMax], ic[objMax],
  1135.     as[objMax], ds[objMax], as1[objMax], ds1[objMax],
  1136.     lo = Lon, longm, w, x, y, z, ad, oa, am, od, dm;
  1137.   int cCross = 0, tot = cObj, i, j, k, l, m, n;
  1138.  
  1139.   if (us.fLatitudeCross)
  1140.     {
  1141.     if ((c = (CrossInfo FPTR *)
  1142.       PAllocate(sizeof(CrossInfo), fFalse, "crossing table")) == NULL)
  1143.       return;
  1144.     }
  1145.  
  1146. #ifdef MATRIX
  1147.   for (i = 1; i <= cObj; i++) if (!ignore[i] || i == oMC) {
  1148.     planet1[i] = RFromD(Tropical(i == oMC ? is.MC : planet[i]));
  1149.     planet2[i] = RFromD(planetalt[i]);     /* Calculate zenith location on */
  1150.     EclToEqu(&planet1[i], &planet2[i]);    /* Earth of each object.        */
  1151.   }
  1152.  
  1153.   /* Print header. */
  1154.  
  1155.   PrintSz("Object :");
  1156.   for (j = 0, i = 1; i <= cObj; i++)
  1157.     if (!ignore[i] && FThing(i)) {
  1158.       AnsiColor(kObjA[i]);
  1159.       sprintf(sz, " %c%c%c", chObj3(i)); PrintSz(sz);
  1160.       j++;
  1161.     }
  1162.   AnsiColor(kDefault);
  1163.   PrintSz("\n------ :");
  1164.   for (i = 1; i <= tot; i++)
  1165.     if (!ignore[i] && FThing(i))
  1166.       PrintSz(" ###");
  1167.  
  1168.   /* Print the longitude locations of the Midheaven lines. */
  1169.  
  1170.   PrintSz("\nMidheav: ");
  1171.   if (lo < 0.0)
  1172.     lo += rDegMax;
  1173.   for (i = 1; i <= tot; i++)
  1174.     if (!ignore[i] && FThing(i)) {
  1175.     AnsiColor(kObjA[i]);
  1176.     x = planet1[oMC]-planet1[i];
  1177.     if (x < 0.0)
  1178.       x += 2.0*rPi;
  1179.     if (x > rPi)
  1180.       x -= 2.0*rPi;
  1181.     z = lo+DFromR(x);
  1182.     if (z > rDegHalf)
  1183.       z -= rDegMax;
  1184.     mc[i] = z;
  1185.     sprintf(sz, "%3.0f%c", RAbs(z), z < 0.0 ? 'e' : 'w'); PrintSz(sz);
  1186.   }
  1187.   AnsiColor(kDefault);
  1188.  
  1189.   /* The Nadir lines are just always 180 degrees away from the Midheaven. */
  1190.  
  1191.   PrintSz("\nNadir  : ");
  1192.   for (i = 1; i <= tot; i++)
  1193.     if (!ignore[i] && FThing(i)) {
  1194.     AnsiColor(kObjA[i]);
  1195.     z = mc[i] + rDegHalf;
  1196.     if (z > rDegHalf)
  1197.       z -= rDegMax;
  1198.     ic[i] = z;
  1199.     sprintf(sz, "%3.0f%c", RAbs(z), z < 0.0 ? 'e' : 'w'); PrintSz(sz);
  1200.   }
  1201.   AnsiColor(kDefault);
  1202.  
  1203.   /* Print the Zenith latitude locations. */
  1204.  
  1205.   PrintSz("\nZenith : ");
  1206.   for (i = 1; i <= tot; i++)
  1207.     if (!ignore[i] && FThing(i)) {
  1208.       AnsiColor(kObjA[i]);
  1209.       y = DFromR(planet2[i]);
  1210.       sprintf(sz, "%3.0f%c", RAbs(y), y < 0.0 ? 's' : 'n'); PrintSz(sz);
  1211.       as[i] = ds[i] = as1[i] = ds1[i] = rLarge;
  1212.     }
  1213.   PrintL2();
  1214.  
  1215.   /* Now print the locations of Ascendant and Descendant lines. Since these */
  1216.   /* are curvy, we loop through the latitudes, and for each object at each  */
  1217.   /* latitude, print the longitude location of the line in question.        */
  1218.  
  1219.   longm = RFromD(Mod(DFromR(planet1[oMC])+lo));
  1220.   for (j = 80; j >= -80; j -= us.nAstroGraphStep) {
  1221.     AnsiColor(kDefault);
  1222.     sprintf(sz, "Asc@%2d%c: ", j >= 0 ? j : -j, j < 0 ? 's' : 'n');
  1223.     PrintSz(sz);
  1224.     for (i = 1; i <= tot; i++)
  1225.       if (!ignore[i] && FThing(i)) {
  1226.       AnsiColor(kObjA[i]);
  1227.       ad = RTan(planet2[i])*RTan(RFromD(j));
  1228.       if (ad*ad > 1.0) {
  1229.         PrintSz(" -- ");
  1230.         as1[i] = ds1[i] = cp2.dir[i] = rLarge;
  1231.       } else {
  1232.         ad = RAsin(ad);
  1233.         oa = planet1[i]-ad;
  1234.         if (oa < 0.0)
  1235.           oa += 2.0*rPi;
  1236.         am = oa-rPiHalf;
  1237.         if (am < 0.0)
  1238.           am += 2.0*rPi;
  1239.         z = longm-am;
  1240.         if (z < 0.0)
  1241.           z += 2.0*rPi;
  1242.         if (z > rPi)
  1243.           z -= 2.0*rPi;
  1244.         as1[i] = as[i];
  1245.         as[i] = z = DFromR(z);
  1246.         cp2.dir[i] = ad;
  1247.         sprintf(sz, "%3.0f%c", RAbs(z), z < 0.0 ? 'e' : 'w'); PrintSz(sz);
  1248.       }
  1249.     }
  1250.  
  1251.     /* Again, the Descendant position is related to the Ascendant's,  */
  1252.     /* being a mirror image, so it can be calculated somewhat easier. */
  1253.  
  1254.     AnsiColor(kDefault);
  1255.     sprintf(sz, "\nDsc@%2d%c: ", j >= 0 ? j : -j, j < 0 ? 's' : 'n');
  1256.     PrintSz(sz);
  1257.     for (i = 1; i <= tot; i++)
  1258.       if (!ignore[i] && FThing(i)) {
  1259.       AnsiColor(kObjA[i]);
  1260.       ad = cp2.dir[i];
  1261.       if (ad == rLarge)
  1262.         PrintSz(" -- ");
  1263.       else {
  1264.         od = planet1[i]+ad;
  1265.         dm = od+rPiHalf;
  1266.         z = longm-dm;
  1267.         if (z < 0.0)
  1268.           z += 2.0*rPi;
  1269.         if (z > rPi)
  1270.           z -= 2.0*rPi;
  1271.         ds1[i] = ds[i];
  1272.         ds[i] = z = DFromR(z);
  1273.         sprintf(sz, "%3.0f%c", RAbs(z), z < 0.0 ? 'e' : 'w'); PrintSz(sz);
  1274.       }
  1275.     }
  1276.     PrintL();
  1277. #endif /* MATRIX */
  1278.  
  1279.     /* Now, if the -L0 switch is in effect, then take these line positions, */
  1280.     /* which we saved in an array above as we were printing them, and       */
  1281.     /* calculate and print the latitude crossings.                          */
  1282.  
  1283.     if (us.fLatitudeCross)
  1284.       for (l = 1; l <= cObj; l++) if (!ignore[l] && FThing(l))
  1285.         for (k = 1; k <= cObj; k++) {
  1286.           if (ignore[k] || !FThing(k))
  1287.             continue;
  1288.           for (n = 0; n <= 1; n++) {
  1289.             x = n ? ds1[l] : as1[l];
  1290.             y = n ? ds[l] : as[l];
  1291.             for (m = 0; m <= 1; m++) {
  1292.  
  1293.             /* Check if Ascendant/Descendant cross Midheaven/Nadir. */
  1294.  
  1295.             z = m ? ic[k] : mc[k];
  1296.             if (cCross < MAXCROSS &&
  1297.               RAbs(x-y) < rDegHalf && RSgn(z-x) != RSgn(z-y)) {
  1298.               c->obj1[cCross] = n ? -l : l;
  1299.               c->obj2[cCross] = m ? -k : k;
  1300.               c->lat[cCross] = (real)j+5.0*RAbs(z-y)/RAbs(x-y);
  1301.               c->lon[cCross] = z;
  1302.               cCross++;
  1303.             }
  1304.  
  1305.             /* Check if Ascendant/Descendant cross another Asc/Des. */
  1306.  
  1307.             w = m ? ds1[k] : as1[k];
  1308.             z = m ? ds[k] : as[k];
  1309.             if (cCross < MAXCROSS && k > l &&
  1310.                 RAbs(x-y)+RAbs(w-z) < rDegHalf && RSgn(w-x) != RSgn(z-y)) {
  1311.               c->obj1[cCross] = n ? -l : l;
  1312.               c->obj2[cCross] = 100+(m ? -k : k);
  1313.               c->lat[cCross] = (real)j+5.0*
  1314.                 RAbs(y-z)/(RAbs(x-w)+RAbs(y-z));
  1315.               c->lon[cCross] = Min(x, y)+RAbs(x-y)*
  1316.                 RAbs(y-z)/(RAbs(x-w)+RAbs(y-z));
  1317.               cCross++;
  1318.             }
  1319.           }
  1320.         }
  1321.     }
  1322.   }
  1323.   if (!us.fLatitudeCross)
  1324.     return;
  1325.   PrintL();
  1326.  
  1327.   /* Now, print out all the latitude crossings we found.  */
  1328.   /* First, we sort them in order of decreasing latitude. */
  1329.  
  1330.   for (i = 1; i < cCross; i++) {
  1331.     j = i-1;
  1332.     while (j >= 0 && c->lat[j] < c->lat[j+1]) {
  1333.       SwapN(c->obj1[j], c->obj1[j+1]); SwapN(c->obj2[j], c->obj2[j+1]);
  1334.       SwapR(&c->lat[j], &c->lat[j+1]); SwapR(&c->lon[j], &c->lon[j+1]);
  1335.       j--;
  1336.     }
  1337.   }
  1338.   for (i = 1; i < cCross; i++) {
  1339.     j = abs(c->obj1[i]);
  1340.     AnsiColor(kObjA[j]);
  1341.     sprintf(sz, "%c%c%c ", chObj3(j)); PrintSz(sz);
  1342.     AnsiColor(kElemA[c->obj1[i] > 0 ? eFir : eAir]);
  1343.     PrintSz(c->obj1[i] > 0 ? "Ascendant " : "Descendant");
  1344.     AnsiColor(kWhite);
  1345.     PrintSz(" crosses ");
  1346.     j = abs(c->obj2[i] - (c->obj2[i] < 50 ? 0 : 100));
  1347.     AnsiColor(kObjA[j]);
  1348.     sprintf(sz, "%c%c%c ", chObj3(j)); PrintSz(sz);
  1349.     AnsiColor(kElemA[c->obj2[i] < 50 ?
  1350.       (c->obj2[i] > 0 ? eEar : eWat) : (c->obj2[i] > 100 ? eFir : eAir)]);
  1351.     sprintf(sz, "%s ", c->obj2[i] < 50 ? (c->obj2[i] > 0 ? "Midheaven " :
  1352.       "Nadir     ") : (c->obj2[i] > 100 ? "Ascendant " : "Descendant"));
  1353.     PrintSz(sz);
  1354.     AnsiColor(kDefault);
  1355.     sprintf(sz, "at %s%c,", SzDegree(c->lon[i]),
  1356.       c->lon[i] < 0.0 ? 'E' : 'W'); PrintSz(sz);
  1357.     j = (int)(RFract(RAbs(c->lat[i]))*60.0);
  1358.     sprintf(sz, "%s%c\n", SzDegree(c->lat[i]),
  1359.       c->lat[i] < 0.0 ? 'S' : 'N'); PrintSz(sz);
  1360.   }
  1361.   DeallocateFar(c);
  1362.   if (!cCross) {
  1363.     AnsiColor(kDefault);
  1364.     PrintSz("No latitude crossings.\n");
  1365.   }
  1366. }
  1367.  
  1368.  
  1369. /* Another important procedure: Display any of the types of (text) charts    */
  1370. /* that the user specified they wanted, by calling the appropriate routines. */
  1371.  
  1372. void PrintChart(fProg)
  1373. bool fProg;
  1374. {
  1375.   int fCall = fFalse;
  1376.  
  1377.   if (us.fListing) {
  1378.     if (is.fMult)
  1379.       PrintL2();
  1380.     if (us.nRel < rcDifference)
  1381.       ChartListing();
  1382.     else
  1383.  
  1384.       /* If the -rb or -rd relationship charts are in effect, then instead  */
  1385.       /* of doing the standard -v chart, print either of these chart types. */
  1386.  
  1387.       DisplayRelation();
  1388.     is.fMult = fTrue;
  1389.   }
  1390.   if (us.fWheel) {
  1391.     if (is.fMult)
  1392.       PrintL2();
  1393.     ChartWheel();
  1394.     is.fMult = fTrue;
  1395.   }
  1396.   if (us.fGrid) {
  1397.     if (is.fMult)
  1398.       PrintL2();
  1399.     if (us.nRel > rcDual) {
  1400.       fCall = us.fSmartCusp; us.fSmartCusp = fFalse;
  1401.       if (!FCreateGrid(fFalse))
  1402.         return;
  1403.       us.fSmartCusp = fCall;
  1404.       not(fCall);
  1405.       ChartGrid();
  1406.       if (us.fGridConfig) {    /* If -g0 switch in effect, then  */
  1407.         PrintL();              /* display aspect configurations. */
  1408.         if (!fCall)
  1409.           FCreateGrid(fFalse);
  1410.         DisplayGrands();
  1411.       }
  1412.     } else {
  1413.  
  1414.       /* Do a relationship aspect grid between two charts if -r0 in effect. */
  1415.  
  1416.       fCall = us.fSmartCusp; us.fSmartCusp = fFalse;
  1417.       if (!FCreateGridRelation(us.fGridConfig))
  1418.         return;
  1419.       us.fSmartCusp = fCall;
  1420.       ChartGridRelation();
  1421.     }
  1422.     is.fMult = fTrue;
  1423.   }
  1424.   if (us.fAspList) {
  1425.     if (is.fMult)
  1426.       PrintL2();
  1427.     if (us.nRel > rcDual) {
  1428.       if (!fCall) {
  1429.         fCall = fTrue;
  1430.         if (!FCreateGrid(fFalse))
  1431.           return;
  1432.       }
  1433.       ChartAspect();
  1434.     } else {
  1435.       if (!FCreateGridRelation(fFalse))
  1436.         return;
  1437.       ChartAspectRelation();
  1438.     }
  1439.     is.fMult = fTrue;
  1440.   }
  1441.   if (us.fMidpoint) {
  1442.     if (is.fMult)
  1443.       PrintL2();
  1444.     if (us.nRel > rcDual) {
  1445.       if (!fCall) {
  1446.         if (!FCreateGrid(fFalse))
  1447.           return;
  1448.       }
  1449.       ChartMidpoint();
  1450.     } else {
  1451.       if (!FCreateGridRelation(fTrue))
  1452.         return;
  1453.       ChartMidpointRelation();
  1454.     }
  1455.     is.fMult = fTrue;
  1456.   }
  1457.   if (us.fHorizon) {
  1458.     if (is.fMult)
  1459.       PrintL2();
  1460.     if (us.fHorizonSearch)
  1461.       ChartInDayHorizon();
  1462.     else
  1463.       ChartHorizon();
  1464.     is.fMult = fTrue;
  1465.   }
  1466.   if (us.fOrbit) {
  1467.     if (is.fMult)
  1468.       PrintL2();
  1469.     ChartOrbit();
  1470.     is.fMult = fTrue;
  1471.   }
  1472.   if (us.fSector) {
  1473.     if (is.fMult)
  1474.       PrintL2();
  1475.     else
  1476.       PrintHeader();    /* Print chart header if it hasn't been done yet. */
  1477.     ChartSector();
  1478.     is.fMult = fTrue;
  1479.   }
  1480.   if (us.fInfluence) {
  1481.     if (is.fMult)
  1482.       PrintL2();
  1483.     ChartInfluence();
  1484.     is.fMult = fTrue;
  1485.   }
  1486.   if (us.fAstroGraph) {
  1487.     if (is.fMult)
  1488.       PrintL2();
  1489.     ChartAstroGraph();
  1490.     is.fMult = fTrue;
  1491.   }
  1492.   if (us.fCalendar) {
  1493.     if (is.fMult)
  1494.       PrintL2();
  1495.     if (us.fCalendarYear)
  1496.       ChartCalendarYear();
  1497.     else
  1498.       ChartCalendarMonth();
  1499.     is.fMult = fTrue;
  1500.   }
  1501.   if (us.fInDay) {
  1502.     if (is.fMult)
  1503.       PrintL2();
  1504.     ChartInDaySearch(fProg);
  1505.     is.fMult = fTrue;
  1506.   }
  1507.   if (us.fInDayInf) {
  1508.     if (is.fMult)
  1509.       PrintL2();
  1510.     ChartInDayInfluence();
  1511.     is.fMult = fTrue;
  1512.   }
  1513.   if (us.fEphemeris) {
  1514.     if (is.fMult)
  1515.       PrintL2();
  1516.     ChartEphemeris();
  1517.     is.fMult = fTrue;
  1518.   }
  1519.   if (us.fTransit) {
  1520.     if (is.fMult)
  1521.       PrintL2();
  1522.     ChartTransitSearch(fProg);
  1523.     is.fMult = fTrue;
  1524.   }
  1525.   if (us.fTransitInf) {
  1526.     if (is.fMult)
  1527.       PrintL2();
  1528.     ChartTransitInfluence(fProg);
  1529.     is.fMult = fTrue;
  1530.   }
  1531. #ifdef ARABIC
  1532.   if (us.nArabic) {
  1533.     if (is.fMult)
  1534.       PrintL2();
  1535.     DisplayArabic();
  1536.     is.fMult = fTrue;
  1537.   }
  1538. #endif
  1539.  
  1540.   if (!is.fMult) {          /* Assume the -v chart if user */
  1541.     us.fListing = fTrue;    /* didn't indicate anything.   */
  1542.     PrintChart(fProg);
  1543.     is.fMult = fTrue;
  1544.   }
  1545. }
  1546.  
  1547. /* charts1.c */
  1548.